<?php

namespace app\shop\controller;

use app\api\service\WechatService;
use app\common\model\Account;
use app\common\service\Status;
use app\shop\model\ShopExpress;
use app\shop\model\ShopGoods;
use app\shop\model\ShopGoodsCate;
use app\shop\model\ShopGoodsSpec;
use app\shop\model\ShopOrder;
use app\shop\model\ShopOrderExpress;
use app\shop\model\ShopOrderGoods;
use buildView\Actions;
use buildView\Button;
use buildView\Filter;
use library\tools\Data;
use think\Controller;
use buildView\Detail;
use buildView\Form;
use buildView\Grid;
use app\shop\model\ShopOrderRefund;
use think\Db;
use think\Exception;
use think\facade\Cache;
use think\facade\Cookie;

/**
 * 售后订单管理
 * Class OrderRefund
 * @package app\shop\controller
 */
class OrderRefund extends Controller
{
    /**
     * 列表
     * @auth true
     * @menu true
     * @return string
     */
    public function index()
    {
        $grid = new Grid(new ShopOrderRefund);
        $grid->setTitle('售后订单管理');
        $grid->user()->nickname('微信昵称')->hide();
        $grid->user()->userInfo();
        $grid->order()->order_no('订单号');
        $grid->type('售后类型')->using(Status::REFUNDTYPE());
        $grid->status('售后状态')->using(Status::REFUNDSTATUS())->badge();
        $grid->price('退款金额');
        $grid->img('售后图片凭证')->image();
        $grid->desc('申请售后描述');
        $grid->create_at('申请时间');

        $grid->actions(function (Actions $action, $data) {
            $action->width(300);
            $action->hideEdit();
            $action->hideDel();
            if ($data['type'] == 1 && $data['status'] == 1) {
                $button = new Button('同意退款');
                $button->save($data['id'], ['status' => 4], url('passRefund'), '确认退款？');
                $action->append($button);
                $button = new Button('拒绝退款', 'danger');
                $button->href(url('refused') . "?id={$data['id']}", 'modal');
                $action->append($button);
            } elseif ($data['type'] == 2 && $data['status'] == 1) {
                $button = new Button('同意换货');
                $button->href(url('passChange') . "?id={$data['id']}", 'modal');
                $action->append($button);
                $button = new Button('拒绝换货', 'danger');
                $button->href(url('refused') . "?id={$data['id']}", 'modal');
                $action->append($button);
            } elseif ($data['type'] == 2 && $data['status'] == 3) {
                $button = new Button('生成换货订单', 'danger');
                $button->href(url('passRefundGoods') . "?refund_id={$data['id']}&back=1");
                $action->append($button);

            }
        });
        $grid->hideDeletesButton();
        $grid->filter(function ($filter) {
            $filter->eq('order.order_no', '订单号');
            $filter->eq('type', '售后类型')->select(Status::REFUNDTYPE());
            $filter->eq('status', '售后状态')->select(Status::REFUNDSTATUS());
        });
        $grid->setFromOpen();
        $grid->hideAddButton();

        return $grid->view();
    }

    /**
     * 选择换货商品
     * @auth true
     * @menu true
     * @Author: rocky
     * 2019/10/9 10:18
     */
    public function selectGoods()
    {
        $grid = new Grid(new ShopGoods());
        $grid->model()->withSum('specs', 'stock')->withSum(['specs' => function ($q) {
            return 'sale_num';
        }], 'sale');
        $grid->logo('商品图片')->width(100)->image(5, 80, 80);
        $grid->column('info', '商品信息')->display(function ($val, $data) {
            $html = "商品编号：{$data['id']}<br>所属分类：{$data['cate']['title']}<br>商品名称：{$data['title']}";
            return $html;
        })->width(200)->align('left');
        $grid->column('specs', '<div class="layui-row" style="line-height:28px">
                    <div class="layui-col-xs6 text-left layui-elip">商品规格</div>
                    <div class="layui-col-xs3 text-center layui-elip">市价 / 售价</div>
                    <div class="layui-col-xs3 text-center layui-elip">库存 / 销量 / 剩余库存</div>
                </div>')
            ->display(function ($specs, $data) {
                $html = '<div class="layui-row" style="line-height:23px">
                        <div class="layui-col-xs6 text-left layui-elip font-s10">--</div>
                        <div class="layui-col-xs3 text-center layui-elip color-blue font-s10">--</div>
                        <div class="layui-col-xs3 text-center layui-elip color-blue font-s10">--</div>
                    </div>';
                if ($specs->isEmpty()) {
                    return $html;
                } else {
                    $html = '<div style="overflow:auto;max-height:68px;padding:5px 0">';
                }
                foreach ($specs as $spec) {
                    $html .= ' <div class="layui-row" style="line-height:23px">
                        <div class="layui-col-xs6 text-left layui-elip font-s10">' . str_replace(['::', ';;'], [':', ';'], $spec['spec_name']) . '</div>
                        <div class="layui-col-xs3 text-center layui-elip color-blue font-s10">' . $spec['price_market'] . ' / ' . $spec['price'] . '</div>
                        <div class="layui-col-xs3 text-center layui-elip color-blue font-s10">' . $spec['stock'] . ' / ' . $spec['sale'] . ' / ' . ($spec['stock'] - $spec['sale']) . '</div>
                    </div>';
                }
                $html .= '</div>';
                return $html;
            })->minWidth(550)->align('left');
        $grid->column('sale_num', '库存统计<br>销量排序')->display(function ($val, $data) {
            $stock = $data['specs_sum'] ? $data['specs_sum'] : 0;
            $sale = $data['sale_num'] ? $data['sale_num'] : 0;
            $stock_num = $stock - $sale;
            if ($stock_num == 0) {
                $stock_num = '<span class="color-red">剩余库存：' . $stock_num . '</span>';
            } else {
                $stock_num = '<span>剩余库存：' . $stock_num . '</span>';
            }
            return '库存：' . $stock . '<br>' . $stock_num . '<br>销量：<span class="layui-badge layui-bg-green">' . $sale . '</span>';
        })->width(150)->align('left')->sort();
        $grid->column('price', '价格')->display(function ($val, $data) {
            return '价格：￥' . $data['price'] . '<br>运费：￥' . $data['price_express'];
        })->width(150)->align('left');

        $grid->hideAction();

        $grid->filter(function (Filter $filter) {
            $filter->like('title', '商品名称');
            $cates = ShopGoodsCate::field('id,title as text,pid')->where('pid', 0)->with(['son' => function ($q) {
                $q->field('id,title as text,pid');
            }])->select();
            $filter->eq('cate_id', '商品分类')->selectGroup($cates);
            $filter->eq('status', '商品状态')->select(Status::SHOPSTATUS());
        });
        $grid->hideExportButton();

        $grid->setIframe('submit', url('passRefundGoods'), $this->request->get('refund_id'));
        return $grid->view();
    }

    /**
     * 售后移除商品
     * @auth true
     * @menu true
     * @Author: rocky
     * 2019/10/9 13:55
     */
    public function removeGood()
    {
        $good_id = $this->request->post('good_id');
        $refund_id = $this->request->post('refund_id');
        $cookieName = 'select_refund_goods' . $refund_id;
        $good = cookie($cookieName);
        if (!empty($good)) {
            $goodArr = explode(',', $good);
            $key = array_search($good_id, $goodArr);

            if ($key !== false) {
                unset($goodArr[$key]);

                $value = implode(',', $goodArr);
                if (empty($value)) {
                    Cookie::delete($cookieName);
                } else {
                    cookie($cookieName, $value);
                }
            }
        }
        $this->success('成功');
    }

    /**
     * 生成换货订单
     * @auth true
     * @menu true
     * @Author: rocky
     * 2019/10/9 9:46
     */
    public function passRefundGoods()
    {
        $refund_id = $this->request->get('refund_id');
        $cookieName = 'select_refund_goods' . $refund_id;
        if ($this->request->isPut()) {
            $good_ids = $this->request->put('select_ids');
            $refund_id = $this->request->put('value');
            $cookieName = 'select_refund_goods' . $refund_id;
            $good = cookie($cookieName);
            if (!empty($good)) {
                $good_ids = $good . ',' . $good_ids;
            }
            cookie($cookieName, $good_ids);
            $this->success('选择完成');
        }
        $good_ids = cookie($cookieName);
        $goods = ShopGoods::whereIn('id', $good_ids)->with(['specs'])->select();
        $form = new Form(new ShopOrder());
        $order_id = ShopOrderRefund::where('id', $refund_id)->value('order_id');
        $order = ShopOrder::find($order_id);
        $form->refund('refund', '选择商品')->value($refund_id)->goodsArr($goods);
        $form->hidden('uid', '用户id')->default($order['uid']);
        $form->text('address_info.name', '姓名')->layui('inline')->default($order['address_info']['name'])->required();
        $form->text('address_info.phone', '手机号')->layui('inline')->default($order['address_info']['phone'])->phone()->required();
        $form->distpicker(['address_info.province', 'address_info.city', 'address_info.area'], '地区')->default([$order['address_info']['province'], $order['address_info']['city'], $order['address_info']['area']])->required();
        $form->text('address_info.address', '详情地址')->default($order['address_info']['address'])->required();
        $wuliu = ShopExpress::where('is_deleted', 0)->column('express_title', 'id');
        $form->select('express_id', '快递公司')->options($wuliu)->required();
        $form->text('number', '快递单号')->required();

        $form->saving(function ($post) {
            $goods = [];
            foreach ($post['spec_id'] as $key => $spec_id) {
                $place['spec_id'] = $spec_id;
                $place['num'] = $post['num'][$key];
                $place['type'] = 2;
                list($msg, $datas) = \app\shop\service\Order::confim($place);

                if ($msg) {
                    Db::rollback();
                    $this->error($msg);
                }
                $goods = array_merge($goods, $datas);
            }

            $order_sn = Data::uniqidDateCode();
            $price_express = 0;
            $total_price = 0;
            $goods_price = 0;
            //统计金额
            foreach ($goods as $data) {
                $goods_price += $data['price'] * $data['num'];
                $total_price += $goods_price + $data['price_express'];
                $price_express += $data['price_express'];
            }
            //商品标题
            $title = $goods[0]['title'];
            if (count($goods) > 1) {
                $title .= '等多件商品';
            }

            //订单数据组装
            $orderData = [
                'title' => $title,
                'type' => 2,
                'order_no' => $order_sn,
                'freight_price' => $price_express,
                'goods_price' => $goods_price,
                'total_price' => 0,
                'pay_type' => 1,
                'address_info' => json_encode($post['address_info'], JSON_UNESCAPED_UNICODE),
                'is_pay' => 1,
                'pay_time' => date('Y-m-d H:i:s'),
                'status' => 3
            ];
            $post = array_merge($post, $orderData);
            session('changeOrder', serialize($goods));
            return $post;

        });
        $form->saved(function ($post, $order) use ($refund_id, $order_id) {
            $datas = unserialize(session('changeOrder'));
            $orderGoods = [];
            $specUpdateData = [];
            foreach ($datas as $data) {
                //销量
                $specUpdateData[] = [
                    'id' => $data['spec_id'],
                    'sale' => Db::raw("sale+{$data['num']}"),
                ];
                //快照组装
                $orderGoods[] = [
                    'order_id' => $order['id'],
                    'good_id' => $data['good_id'],
                    'spec_id' => $data['spec_id'],
                    'good_title' => $data['title'],
                    'good_logo' => $data['logo'],
                    'spec_name' => $data['spec'],
                    'spec_img' => $data['img'],
                    'price' => $data['price'],
                    'num' => $data['num'],
                ];
            }
            (new ShopGoodsSpec())->saveAll($specUpdateData);
            (new ShopOrderGoods())->saveAll($orderGoods);
            $wuliu = ShopExpress::get($post['express_id']);
            ShopOrderExpress::create([
                'express_id' => $post['express_id'],
                'number' => $post['number'],
                'order_id' => $order['id'],
                'company' => $wuliu['express_title'],
                'mark' => $wuliu['express_code']
            ]);
            ShopOrder::where('id', $order_id)->setField('status', -1);
            $refund = ShopOrderRefund::find($refund_id);
            if ($refund['status'] != 3) {
                Db::rollback();
                $this->error('售后已完成,请返回');
            }
            $refund->status = 5;
            $refund->save();
        });
        $form->setSubmitText('生成订单发货');
        return $form->view();
    }

    /**
     * 同意退款
     * @auth true
     * @menu true
     * @Author: rocky
     * 2019/10/8 17:08
     */
    public function passRefund()
    {
        $refund_id = $this->request->post('id');
        $refund = ShopOrderRefund::where('status', 1)->get($refund_id, ['order']);
        if ($refund) {
            $order = $refund['order'];
            Db::startTrans();
            try {
                $res = WechatService::refund($order['pay_no'], $order['order_no'], $order['total_price'], $refund['price']);
                if ($res) {
                    $refund->status = 4;
                    $refund->complete_time = date('Y-m-d H:i:s');
                    $refund->save();
                    ShopOrder::where('id', $order['id'])->setField('status', -1);
                    Account::create([
                        'uid' => $order['uid'],
                        'title' => "退款微信钱包 - 订单[{$order['title']}]",
                        'desc' => "退款微信钱包 - 订单号：{$order['order_no']}",
                        'money' => $refund['price'],
                        'type' => 2
                    ]);
                    Db::commit();
                    $this->success('退款成功');
                } else {
                    Db::rollback();
                    $this->error('退款失败', '');
                }
            } catch (\Exception $e) {
                Db::rollback();
                $this->error('退款失败:'.$e->getMessage(), '');
            }
        } else {
            $this->error('售后失败，订单无效', '');
        }
    }

    /**
     * 同意换货
     * @auth true
     * @menu true
     * @Author: rocky
     * 2019/10/9 9:17
     * @return string
     */
    public function passChange()
    {
        $form = new Form(new ShopOrderRefund);
        $address = unserialize(Cache::get('refund_change_address'));
        $form->text('address_info.name', '姓名')->default($address['name'])->required();
        $form->text('address_info.phone', '手机号')->default($address['phone'])->phone()->required();
        $form->distpicker(['address_info.province', 'address_info.city', 'address_info.area'], '地区')->default([$address['province'], $address['city'], $address['area']])->required();
        $form->text('address_info.address', '详情地址')->default($address['address'])->required();
        $form->hidden('status', '状态')->value(2);
        $form->saving(function ($post, $model) {
            $post['address_info']['province'] = $post['address_info_province'];
            $post['address_info']['city'] = $post['address_info_city'];
            $post['address_info']['area'] = $post['address_info_area'];
            $post['address_info']['full_address'] = $post['address_info_province'] . $post['address_info_city'] . $post['address_info_area'] . $post['address_info']['address'];
            $model->json(['address_info'])->strict(false)->update($post);
            Cache::set('refund_change_address', serialize($post['address_info']));
        });
        return $form->view();

    }

    /**
     * 拒绝售后
     * @auth true
     * @menu true
     * @Author: rocky
     * 2019/10/9 16:07
     */
    public function refused()
    {
        $form = new Form(new ShopOrderRefund);
        $form->textarea('content', '拒绝理由');
        $form->hidden('status', '状态')->value(0);
        return $form->view();

    }

    /**
     * 详情
     * @auth true
     * @menu true
     * @return string
     */
    public function detail()
    {
        $detail = new Detail(new ShopOrderRefund);
        $data = $detail->getModelData();
        if ($data['type'] == 2) {
            $md = 6;
        } else {
            $md = 12;
        }
        $detail->layout('售后信息', $md, function ($detail) use ($data) {
            if ($data['type'] == 1 && $data['status'] == 1) {
                $detail->column('action', '')->display(function () use ($data) {
                    $html = '';
                    $button = new Button('同意退款');
                    $button->save($data['id'], ['status' => 2], url('passRefund'), '确认退款？');
                    $html .= $button->render();
                    $button = new Button('拒绝退款', 'danger');
                    $button->href(url('refused') . "?id={$data['id']}", 'modal');
                    $html .= $button->render();
                    return $html;
                });
            } elseif ($data['type'] == 2 && $data['status'] == 1) {
                $detail->column('action', '')->display(function () use ($data) {
                    $html = '';
                    $button = new Button('同意换货');
                    $button->href(url('passChange') . "?id={$data['id']}", 'modal');
                    $html .= $button->render();
                    $button = new Button('拒绝换货', 'danger');
                    $button->href(url('refused') . "?id={$data['id']}", 'modal');
                    $html .= $button->render();
                    return $html;
                });
            }
            $detail->user()->nickname('会员昵称');
            $detail->user()->headimg('会员头像')->image(50, 50, 50);
            $detail->type('售后类型')->using(Status::REFUNDTYPE());
            $detail->order()->order_no('订单号');
            $detail->status('售后状态')->using(Status::REFUNDSTATUS())->badge();
            $detail->price('退款金额');
            $detail->refund_price('实际退款金额');
            $detail->img('售后图片凭证')->image();
            $detail->desc('申请售后描述');
            $detail->create_at('申请时间');
            $detail->complete_time('完成时间');
        });
        if ($data['type'] == 2) {
            $detail->layout('换货地址', 6, function ($detail) {
                $detail->address_info()->name('姓名');
                $detail->address_info()->phone('联系电话');
                $detail->address_info('地址')->display(function ($val) {
                    return "{$val['province']}{$val['city']}{$val['area']}{$val['address']}";
                });
            });
            $detail->layout('用户寄回', 6, function ($detail) {
                $detail->express_compay('快速公司');
                $detail->express_number('快递单号');
            });
        }
        return $detail->view();
    }
}
